package com.sh.entity;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sh.service.UserService;
import com.sh.util.JwtUtil;

/**
 * 自定义Realm
 */
@Service
public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    /**
     * 大坑，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken authenticationToken) {
        return authenticationToken instanceof JwtToken;
    }

    /**
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    	String username = JwtUtil.getUsername(principals.toString());
    	User user = 
    			userService.getUserByName(username);
    	SimpleAuthorizationInfo simpleAuthorizationInfo = 
			 new SimpleAuthorizationInfo();
		//角色列表
		List<String> roleIdList = new ArrayList<String>();
		List<Role> role = user.getRole();
		for(Role r:role){
			roleIdList.add(r.getRoleId());
		}
		simpleAuthorizationInfo.addRoles(roleIdList);
		
		//角色对应的权限控制
		Set<String> permission = new HashSet<>();
		permission.add("EDIT");
		permission.add("VIEW");
        simpleAuthorizationInfo.addStringPermissions(permission);;
        return simpleAuthorizationInfo;
    }

    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = 
        		(String) authenticationToken.getCredentials();
        // 根据token拿取用户名
        String username = 
        		JwtUtil.getUsername(token);
        // 如果没有登录
        if (username==null) {
            throw new AuthenticationException("Token为空或者失效(The account in Token is empty.)");
        }
        // 验证用户名
        User user = 
    			userService.getUserByName(username);
		
        if (user == null) {
            throw new AuthenticationException("账户不存在");
        }

        if (! JwtUtil.verify(token, username, user.getPwd())) {
            throw new AuthenticationException("认证失败！");
        }

        return new SimpleAuthenticationInfo(token, token, "userRealm");
    }

}
